/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*-  */
/*
 * LiberAcus
 * Copyright (C) 2012 - 2014 Massimiliano Maniscalco <max.maniscalco@gmail.com>
 * 
LiberAcus is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * LiberAcus is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _CONTROLLER_H_
#define _CONTROLLER_H_

#include <gtkmm.h>
#include <giomm/file.h>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <set>
#include <map>
#include "cliente.h"
#include "prestazione.h"
#include "ricevuta.h"
#include "popup_button_model.h"
#include "clienti_list_model.h"
#include "prestazioni_list_model.h"
#include "prestazioni_ricevuta_tree_model.h"
#include "ricevute_list_model.h"
#include "ricevute_giorno_list_model.h"
#include "ricevute_resoconto_list_model.h"
#include "utility.h"
#include "preferenze.h"

class RicevutaPrintFormOperation;

#define STATUS_STARTING		0
#define STATUS_LOADING		1
#define STATUS_RUNNING		2

#define SAVE_CLIENTI			0
#define SAVE_PRESTAZIONI	1
#define SAVE_RICEVUTE			2

#define PAGINA_CALENDARIO		0
#define PAGINA_RICEVUTE			1
#define PAGINA_PRESTAZIONI		2
#define PAGINA_CLIENTI				3
#define PAGINA_RESOCONTO		4

#define UN_GIORNO				86400
#define TRE_GIORNI				259200

// holidays
#define SABATO					(data_ora->tm_wday == 6)
#define DOMENICA				(data_ora->tm_wday == 0)
#define PRIMO_GENNAIO		(data_ora->tm_mon == 0 && data_ora->tm_mday == 1)
#define EPIFANIA					(data_ora->tm_mon == 0 && data_ora->tm_mday == 6)
#define LIBERAZIONE				(data_ora->tm_mon == 3 && data_ora->tm_mday == 25)
#define PRIMO_MAGGIO			(data_ora->tm_mon == 4 && data_ora->tm_mday == 1)
#define FESTA_REPUBBLICA	(data_ora->tm_mon == 5 && data_ora->tm_mday == 2)
#define ASSUNZIONE				(data_ora->tm_mon == 7 && data_ora->tm_mday == 15)
#define TUTTI_SANTI				(data_ora->tm_mon == 10 && data_ora->tm_mday == 1)
#define IMMACOLATA				(data_ora->tm_mon == 11 && data_ora->tm_mday == 8)
#define NATALE						(data_ora->tm_mon == 11 && data_ora->tm_mday == 25)
#define SANTO_STEFANO		(data_ora->tm_mon == 11 && data_ora->tm_mday == 26)

using namespace std;

class Controller
{
public:
	inline static time_t calcola_data_ritiro ( time_t tempo );
	inline static time_t parse_data_string ( const Glib::ustring &str );
	inline static void calcola_periodo_tempo ( time_t &inizio, time_t &fine, char periodo );
	
	inline Controller() : clienti_file_path ( "" ), prestazioni_file_path ( "" ), ricevute_file_path ( "" ), clienti_changed ( false ), prestazioni_changed ( false ), ricevute_changed ( false )
	{}
	inline Controller ( Glib::RefPtr<Gtk::Builder> bldr, Glib::RefPtr<Gtk::Application> app );
	inline ~Controller();
	inline bool should_save ( void ) const { return clienti_changed || prestazioni_changed || ricevute_changed; }
	inline bool should_save_clienti ( void ) const { return clienti_changed; }
	inline bool should_save_prestazioni ( void ) const { return prestazioni_changed; }
	inline bool should_save_ricevute ( void ) const { return ricevute_changed; }
	inline Glib::ustring get_clienti_file_path ( void ) const { return clienti_file_path; }
	inline Glib::ustring get_prestazioni_file_path ( void ) const { return prestazioni_file_path; }
	inline Glib::ustring get_ricevute_file_path ( void ) const { return ricevute_file_path; }
	inline Gtk::Window* get_main_window ( void ) const { return main_window; }
	bool save_data ( const Glib::ustring &filename, char what );
	bool chiedi_prima_salvare ( void ) const { return preferenze.get_salvataggio_automatico (); }

protected:
	void load_data ( void );
	bool load_clienti_from_xml_file ( const Glib::ustring &filename );
	bool load_prestazioni_from_xml_file ( const Glib::ustring &filename );
	bool load_ricevute_from_xml_file ( const Glib::ustring &filename );
	template <class ItemClass>
	int save_items_to_xml_file ( list<ItemClass> &items_list, ofstream *xmlstr );
	template <class ItemClass>
	int save_items_to_xml_file ( set<ItemClass> &items_set, ofstream *xmlstr );
	void load_preferences ( const Glib::ustring &filename );
	bool save_preferences ( const Glib::ustring &filename );
	template <class ItemClass, typename Iterator>
	void replace_items ( set<ItemClass>* items_set, Iterator iter, const ItemClass& item );
	void connect_signals ( void );
	void on_cancel_button_clicked ( Gtk::Window *win );
	bool on_auto_save_fired ( void );
	
	// main win
	bool on_main_window_focus_in ( GdkEventFocus *event );
	bool on_main_window_focus_out ( GdkEventFocus *event );
	void on_main_notebook_page_switch ( Gtk::Widget *page, guint page_num );
	void on_items_treeselection_changed ( void );
	void get_treeview_row_reference ( const vector<Gtk::TreePath> &_sel, Glib::RefPtr<Gtk::TreeModel> _listModel, vector<Gtk::TreeRowReference> &_selRef );
	void load_popup_button ( vector<Glib::ustring>::iterator start, vector<Glib::ustring>::iterator end, Glib::RefPtr<Gtk::ListStore> popUpList );
	set<Prestazione>::iterator find_prestazione ( const Glib::ustring& capo, const Glib::ustring& descrizione );
	// main toolbar
	void on_new_ricevuta_action ( void );
	void on_new_prestazione_action ( void );
	void on_new_cliente_action ( void );
	void on_edit_item_action ( void );
	void on_remove_item_action ( void );
	void on_stampa_chiusura_cassa_action ( void );
	// main menu
	void on_save_action ( void );
	void on_page_setup_action ( void );
	void on_print_ricevuta_action ( void );
	void on_print_etichette_action ( void );
	void on_quit_app_action ( void );
	void on_preferenze_action ( void );
	void on_visualizza_action ( const unsigned short );
	void on_about_app_action ( void );
	void on_about_response ( int response_id, Gtk::AboutDialog *about_dialog );

	/**
	 * main notebook
	 * */
	
	void on_treeview_clicked ( GdkEventButton *event );

	// page calendario
	void aggiorna_pagina_calendario ( void );
	float load_ricevute_del_giorno_in_treeview ( Glib::RefPtr<Gtk::ListStore> liststore, time_t tempo );
	void on_ricevute_del_giorno_treeselection_changed ( const short sender );
	void aggiorna_dettagli_ricevuta_calendario ( const Ricevuta &rcvt );
	void on_calendario_prestazione_completa_toggled ( const Glib::ustring &path );
	void load_riepilogo_prestazioni_in_treeview ( void );

	// page ricevute
	void load_ricevute_in_treeview ( bool filtro = false );
	set<Ricevuta>::iterator get_ricevuta_iterator ( Gtk::TreeModel::Row row );
	void ricevute_treeview_remove_selected_rows ( const vector<Gtk::TreePath> &sel );
	void ricevute_treeview_edit_selected_rows ( const vector<Gtk::TreePath> &sel );
	void on_ricevuta_urgente_toggled ( const Glib::ustring &path );
	void on_ricevuta_consegnato_toggled ( const Glib::ustring &path );

	// page prestazioni
	void load_prestazioni_in_treeview ( void );
	set<Prestazione>::iterator get_prestazione_iterator ( Gtk::TreeModel::Row row );
	void prestazioni_treeview_remove_selected_rows ( const vector<Gtk::TreePath> &sel );
	void prestazioni_treeview_edit_selected_rows ( const vector<Gtk::TreePath> &sel );

	// page clienti
	void load_clienti_in_treeview ( void );
	set<Cliente>::iterator get_cliente_iterator ( Gtk::TreeModel::Row row );
	void clienti_treeview_remove_selected_rows ( const vector<Gtk::TreePath> &sel );
	void clienti_treeview_edit_selected_rows ( const vector<Gtk::TreePath> &sel );

	// page resoconto
	void aggiorna_pagina_resoconto ( void );

	// nuova ricevuta window
	void disconnect_capo_popup ( void );
	void reconnect_capo_popup ( void );
	void disconnect_prestazione_popup ( void );
	void reconnect_prestazione_popup ( void );
	void disconnect_prestazioni_ricevuta ( void );
	void reconnect_prestazioni_ricevuta ( void );
	void load_capo_popup_button ( void );
	void load_prestazione_popup_button ( void );
	void load_clienti_in_ricevuta_completion ( void );
	void on_trova_clienti_action ( void );
	void on_cambia_data_ricevuta_action ( Gtk::Button *sender );
	void load_prestazioni_ricevuta_in_treeview ( list<Capo>::const_iterator iter, list<Capo>::const_iterator end );
	Gtk::TreeModel::Path get_prestazione_ricevuta_selezionata ( void );
	void on_prestazioni_ricevuta_selection_changed ( void );
	bool update_capo_popup_button ( const Glib::ustring capo );
	void update_prestazioni_popup_button ( const Glib::ustring descrizione );
	void on_prestazioni_ricevuta_row_expanded (const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path);
	void on_selezione_prestazione_popup_changed ( void );
	void on_add_prestazione_ricevuta_action ( void );
	void riordina_numeri_capi ( void );
	void on_remove_prestazione_ricevuta_action ( void );
	void on_prezzo_modificato ( const Glib::ustring& path, const Glib::ustring& new_text );
	void update_totale_nuova_ricevuta ( float delta );
	float ricalcola_totale_nuova_ricevuta ( void );
	void on_pagamento_anticipato_toggled ( void );
	void on_conferma_ricevuta_button_action ( void );

	// nuova prestazione window
	void load_capi_in_prestazione_completion ( void );
	void on_new_prestazione_confirm_button_clicked ( void );

	// nuovo cliente window
	void on_new_cliente_confirm_button_clicked ( void );

	// calendario window
	void on_calendario_window_hide ( void );
	void on_data_modificata ( void );

	// preferenze window
	void on_visualizza_numero_toggled(void);
	void update_visualizza_numero(bool visualizza);
	void on_salva_preferenze_action ( void );
	bool eliminazione_automatica ( void );

	// suggerimento clienti window
	void load_clienti_in_finestra_suggerimento ( void );
	void on_suggerimento_clienti_double_clicked ( GdkEventButton *event );

	// parser xml
	void on_signal_preferenze_loaded ( const Preferenze& pref );
	void on_signal_preferenze_loading_end ( void );
	void on_signal_date_file ( time_t tempo );
	void on_signal_cliente_loaded ( const Cliente &clnt );
	void on_signal_prestazione_loaded ( const Prestazione &prst );
	void on_signal_ricevuta_loaded ( const Ricevuta &rcvt );
	void on_signal_importing_clienti_end ( void );
	void on_signal_importing_prestazioni_end ( void );
	void on_signal_importing_ricevute_end ( void );

	// printing
	Glib::ustring get_stampa_prestazioni ( set<Ricevuta>::const_iterator iter, size_t line );
	void on_printoperation_status_changed(const Glib::RefPtr<Gtk::PrintOperation>& operation);
	void on_printoperation_done(Gtk::PrintOperationResult result, const Glib::RefPtr<Gtk::PrintOperation>& operation);
	void print_or_preview_ricevuta(Gtk::PrintOperationAction print_action, const Glib::ustring &str1);
	void print_or_preview_etichetta(Gtk::PrintOperationAction print_action, const Glib::ustring &str1);
	void print_or_preview_chiusura(Gtk::PrintOperationAction print_action, const Glib::ustring &str1);

private:
	Glib::RefPtr<Gtk::Application> this_app;
	char starting_app;
	bool clienti_changed;
	bool prestazioni_changed;
	bool ricevute_changed;
	unsigned int ricevute_caricate;
	unsigned int prestazioni_caricate;
	unsigned int clienti_caricati;
	Glib::ustring clienti_file_path;
	Glib::ustring prestazioni_file_path;
	Glib::ustring ricevute_file_path;
	Glib::ustring pref_path;
	Glib::ustring page_setup_path;
	Glib::KeyFile* printer_keyfile;
	Preferenze preferenze;
	set<Cliente>* clienti;
	set<Prestazione>* prestazioni;
	set<Ricevuta>* ricevute;
	map<Glib::ustring,int>* mappa_capi;
	sigc::connection save_timer_connection;
	// main window
	Gtk::Window* main_window;
	Gtk::Notebook* main_notebook;
	Gtk::Statusbar* main_statusbar;
	unsigned short main_notebook_page;
	PopUpButtonModel* button_popup_listmodel;
	int stbrItemSelId;
	int stbrItemDiskId;
	int stbrPrintId;

	// main toolbar
	Gtk::Toolbar* main_toolbar;
	Gtk::Button* nuova_ricevuta_button;
	Gtk::Button* nuova_prestazione_button;
	Gtk::Button* nuovo_cliente_button;
	Gtk::ToolButton* modifica_selezione_toolbutton;
	Gtk::ToolButton* elimina_selezione_toolbutton;
	Gtk::ToolButton* stampa_chiusura_toolbutton;

	// main menu
	Gtk::MenuBar* main_menubar;
	Gtk::ImageMenuItem* nuova_ricevuta_menuitem;
	Gtk::ImageMenuItem* nuova_prestazione_menuitem;
	Gtk::ImageMenuItem* nuovo_cliente_menuitem;
	Gtk::ImageMenuItem* salva_menuitem;
	Gtk::ImageMenuItem* imposta_pagina_menuitem;
	Gtk::ImageMenuItem* stampa_ricevuta_menuitem;
	Gtk::ImageMenuItem* stampa_etichette_menuitem;
	Gtk::ImageMenuItem* stampa_chiusura_menuitem;
	Gtk::ImageMenuItem* quit_menuitem;
	Gtk::ImageMenuItem* modifica_selezione_menuitem;
	Gtk::ImageMenuItem* elimina_selezione_menuitem;
	Gtk::ImageMenuItem* preferenze_menuitem;
	Gtk::ImageMenuItem* settimana_menuitem;
	Gtk::ImageMenuItem* ricevute_menuitem;
	Gtk::ImageMenuItem* prestazioni_menuitem;
	Gtk::ImageMenuItem* clienti_menuitem;
	Gtk::ImageMenuItem* resoconto_menuitem;
	Gtk::ImageMenuItem* about_menuitem;

	/**
	 * main notebook
	 * */

	// page calendario
	RicevuteGiornoListModel* ricevute_giorno_listmodel;
	Gtk::Label* calendario_lunedi_label;
	Glib::RefPtr<Gtk::ListStore> ricevute_lunedi_liststore;
	Gtk::TreeView* ricevute_lunedi_treeview;
	Glib::RefPtr<Gtk::TreeSelection> ricevute_lunedi_treeselection;
	Gtk::TreeViewColumn* numero_ricevuta_lunedi_treeviewcolumn;
	Gtk::Label* totale_lunedi_label;
	Gtk::Label* calendario_martedi_label;
	Glib::RefPtr<Gtk::ListStore> ricevute_martedi_liststore;
	Gtk::TreeView* ricevute_martedi_treeview;
	Glib::RefPtr<Gtk::TreeSelection> ricevute_martedi_treeselection;
	Gtk::TreeViewColumn* numero_ricevuta_martedi_treeviewcolumn;
	Gtk::Label* totale_martedi_label;
	Gtk::Label* calendario_mercoledi_label;
	Glib::RefPtr<Gtk::ListStore> ricevute_mercoledi_liststore;
	Gtk::TreeView* ricevute_mercoledi_treeview;
	Glib::RefPtr<Gtk::TreeSelection> ricevute_mercoledi_treeselection;
	Gtk::TreeViewColumn* numero_ricevuta_mercoledi_treeviewcolumn;
	Gtk::Label* totale_mercoledi_label;
	Gtk::Label* calendario_giovedi_label;
	Glib::RefPtr<Gtk::ListStore> ricevute_giovedi_liststore;
	Gtk::TreeView* ricevute_giovedi_treeview;
	Glib::RefPtr<Gtk::TreeSelection> ricevute_giovedi_treeselection;
	Gtk::TreeViewColumn* numero_ricevuta_giovedi_treeviewcolumn;
	Gtk::Label* totale_giovedi_label;
	Gtk::Label* calendario_venerdi_label;
	Glib::RefPtr<Gtk::ListStore> ricevute_venerdi_liststore;
	Gtk::TreeView* ricevute_venerdi_treeview;
	Glib::RefPtr<Gtk::TreeSelection> ricevute_venerdi_treeselection;
	Gtk::TreeViewColumn* numero_ricevuta_venerdi_treeviewcolumn;
	Gtk::Label* totale_venerdi_label;
	Gtk::Label* calendario_sabato_label;
	Glib::RefPtr<Gtk::ListStore> ricevute_sabato_liststore;
	Gtk::TreeView* ricevute_sabato_treeview;
	Glib::RefPtr<Gtk::TreeSelection> ricevute_sabato_treeselection;
	Gtk::TreeViewColumn* numero_ricevuta_sabato_treeviewcolumn;
	Gtk::Label* totale_sabato_label;
	Gtk::Label* calendario_dettaglio_numero_label;
	Gtk::Label* calendario_dettaglio_cliente_label;
	Gtk::Label* calendario_dettaglio_accettazione_label;
	Gtk::Label* calendario_dettaglio_ritiro_label;
	Gtk::Label* calendario_dettaglio_acconto_label;
	Gtk::Label* calendario_dettaglio_totale_label;
	Glib::RefPtr<Gtk::TreeStore> calendario_dettaglio_prestazioni_treestore;
	Gtk::TreeView* calendario_dettaglio_prestazioni_treeview;
	Glib::RefPtr<Gtk::TreeSelection> calendario_dettaglio_prestazioni_treeselection;
	Gtk::TreeViewColumn* completoTreeviewcolumn;
	Gtk::CellRendererToggle* completoCellrenderertoggle;
	Glib::RefPtr<Gtk::TreeStore> calendario_riepilogo_prestazioni_treestore;
	Gtk::TreeView* calendario_riepilogo_prestazioni_treeview;

	// page ricevute
	RicevuteListModel* ricevute_listmodel;
	Glib::RefPtr<Gtk::ListStore> ricevute_liststore;
	Gtk::TreeView* ricevute_treeview;
	Glib::RefPtr<Gtk::TreeSelection> ricevute_treeselection;
	Gtk::TreeViewColumn* numero_ricevuta_treeviewcolumn;
	Gtk::TreeViewColumn* urgente_treeviewcolumn;
	Gtk::CellRendererToggle* urgente_cellrenderertoggle;
	Gtk::TreeViewColumn* consegnato_treeviewcolumn;
	Gtk::CellRendererToggle* consegnato_cellrenderertoggle;

	// menu contestuale ricevute
	Gtk::Menu* ricevute_context_menu;
	Gtk::MenuItem* modifica_ricevute_context_menuitem;
	Gtk::MenuItem* elimina_ricevute_context_menuitem;
	Gtk::MenuItem* stampa_ricevute_context_menuitem;
	Gtk::MenuItem* stampa_etichette_context_menuitem;

	// page prestazioni
	PrestazioniListModel* prestazioni_listmodel;
	Glib::RefPtr<Gtk::ListStore> prestazioni_liststore;
	Gtk::TreeView* prestazioni_treeview;
	Glib::RefPtr<Gtk::TreeSelection> prestazioni_treeselection;

	// page clienti
	ClientiListModel* clienti_listmodel;
	Glib::RefPtr<Gtk::ListStore> clienti_liststore;
	Gtk::TreeView* clienti_treeview;
	Glib::RefPtr<Gtk::TreeSelection> clienti_treeselection;

	// menu contestuale generico
	Gtk::Menu* generic_context_menu;
	Gtk::MenuItem* edit_generic_context_menuitem;
	Gtk::MenuItem* remove_generic_context_menuitem;

	// page resoconto
	Gtk::ComboBox* selezione_periodo_combobox;
	Glib::RefPtr<Gtk::ListStore> selezione_periodo_liststore;
	Gtk::Label* resoconto_ricevute_emesse_label;
	Gtk::Label* resoconto_prestazioni_effettuate_label;
	Gtk::Label* resoconto_clienti_serviti_label;
	Gtk::Label* resoconto_incasso_totale_label;
	RicevuteResocontoListModel* ricevute_resoconto_listmodel;
	Glib::RefPtr<Gtk::ListStore> ricevute_resoconto_liststore;
	Gtk::TreeView* ricevute_resoconto_treeview;
	Glib::RefPtr<Gtk::ListStore> prestazioni_resoconto_liststore;
	Gtk::TreeViewColumn* numero_ricevuta_resoconto_treeviewcolumn;
	Gtk::TreeView* prestazioni_resoconto_treeview;
	Glib::RefPtr<Gtk::ListStore> clienti_resoconto_liststore;
	Gtk::TreeView* clienti_resoconto_treeview;

	// nuova ricevuta window
	Gtk::Window* new_ricevuta_window;
	Gtk::Entry* cliente_ricevuta_entry;
	Glib::RefPtr<Gtk::EntryCompletion> nome_cliente_entrycompletion;
	Glib::RefPtr<Gtk::ListStore> nome_cliente_liststore;
	Gtk::Button* trova_clienti_button;
	Gtk::Entry* data_accettazione_ricevuta_entry;
	Gtk::Button* cambia_data_ricevuta_button1;
	PrestazioniRicevutaTreeModel* prestazioni_ricevuta_treemodel;
	Glib::RefPtr<Gtk::TreeStore> prestazioni_ricevuta_treestore;
	Gtk::TreeView* prestazioni_ricevuta_treeview;
	Glib::RefPtr<Gtk::TreeSelection> prestazioni_ricevuta_treeselection;
	sigc::connection prestazioni_ricevuta_connection;
	Gtk::TreeViewColumn* prezzo_prestazione_treeviewcolumn;
	Gtk::CellRendererText* prezzo_prestazione_cellrenderertext;
	Gtk::ComboBox* selezione_capo_combobox;
	Glib::RefPtr<Gtk::ListStore> selezione_capo_liststore;
	sigc::connection capo_popup_connection;
	Gtk::ComboBox* selezione_prestazione_combobox;
	Glib::RefPtr<Gtk::ListStore> selezione_prestazione_liststore;
	sigc::connection prestazione_popup_connection;
	Gtk::Button* add_prestazione_ricevuta_button;
	Gtk::Button* rem_prestazione_ricevuta_button;
	Gtk::Entry* data_ritiro_ricevuta_entry;
	Gtk::Button* cambia_data_ricevuta_button2;
	Gtk::Label* totale_ricevuta_label;
	Gtk::RadioButton* nonpagato_radiobutton;
	Gtk::RadioButton* pagato_radiobutton;
	Gtk::Entry* acconto_ricevuta_entry;
	Gtk::CheckButton* stampa_ricevuta_checkbutton;
	Gtk::CheckButton* urgente_ricevuta_checkbutton;
	Gtk::Button* new_ricevuta_cancel_button;
	Gtk::Button* new_ricevuta_confirm_button;

	// nuova prestazione window
	Gtk::Window* new_prestazione_window;
	Gtk::Entry* capo_prestazione_entry;
	Glib::RefPtr<Gtk::EntryCompletion> capo_entrycompletion;
	Glib::RefPtr<Gtk::ListStore> capo_liststore;
	Gtk::Entry* descrizione_prestazione_entry;
	Gtk::Entry* prezzo_prestazione_entry;
	Gtk::Button* new_prestazione_confirm_button;
	Gtk::Button* new_prestazione_cancel_button;

	// nuovo cliente window
	Gtk::Window* new_cliente_window;
	Gtk::Entry* nome_cliente_entry;
	Gtk::Entry* telefono_cliente_entry;
	Gtk::Button* new_cliente_confirm_button;
	Gtk::Button* new_cliente_cancel_button;

	// calendario window
	Gtk::Window* calendario_window;
	Gtk::Calendar* main_calendar;
	sigc::connection data_modificata_connection;

	// preferenze window
	Gtk::Window* preferenze_window;
	Gtk::TextView* intestazione_textview;
	Glib::RefPtr<Gtk::TextBuffer> intestazione_textbuffer;
	Gtk::TextView* saluto_textview;
	Glib::RefPtr<Gtk::TextBuffer> saluto_textbuffer;
	Gtk::Button* preferenze_salva_button;
	Gtk::Button* preferenze_annulla_button;
	Gtk::ComboBox* eliminazione_ricevute_combobox;
	Glib::RefPtr<Gtk::ListStore> eliminazione_ricevute_liststore;
	Gtk::ComboBox* azzeramento_numero_combobox;
	Glib::RefPtr<Gtk::ListStore> azzeramento_numero_liststore;
	Gtk::ComboBox* salvataggio_uscita_combobox;
	Glib::RefPtr<Gtk::ListStore> salvataggio_uscita_liststore;
	Gtk::CheckButton* stampa_numero_ricevuta_checkbutton;
	Gtk::CheckButton* visualizza_numero_ricevuta_checkbutton;

	// suggerimento clienti window
	Gtk::Window* suggerimento_clienti_window;
	Glib::RefPtr<Gtk::ListStore> clienti_suggerimento_liststore;
	Gtk::TreeView* clienti_suggerimento_treeview;
	Glib::RefPtr<Gtk::TreeSelection> clienti_suggerimento_treeselection;

	// printing
	Glib::RefPtr<Gtk::PageSetup> m_refPageSetup;
	Glib::RefPtr<Gtk::PrintSettings> m_refSettings;

};

inline Controller::
Controller( Glib::RefPtr<Gtk::Builder> bldr, Glib::RefPtr<Gtk::Application> app ) :
	this_app ( app ), clienti_changed ( false ), prestazioni_changed ( false ), ricevute_changed ( false ), starting_app ( STATUS_STARTING ), clienti ( new set<Cliente> ), prestazioni ( new set<Prestazione> ), ricevute ( new set<Ricevuta> ),
	preferenze ( Preferenze() ), mappa_capi ( new map<Glib::ustring,int> )
{
	// general init
	button_popup_listmodel = new PopUpButtonModel ();
	// working directory
	Glib::ustring main_directory ( Glib::get_home_dir () + Glib::ustring ( "/.LiberAcus" ) );
	Glib::RefPtr<Gio::File> main_dir_file = Gio::File::create_for_path ( main_directory );
	if ( !main_dir_file->query_exists () )
		main_dir_file->make_directory ();
	clienti_file_path = main_directory + Glib::ustring ( "/LiberAcus_clienti.xml" );
	prestazioni_file_path = main_directory + Glib::ustring ( "/LiberAcus_prestazioni.xml" );
	ricevute_file_path = main_directory + Glib::ustring ( "/LiberAcus_ricevute.xml" );
	pref_path = main_directory + Glib::ustring ( "/preferences.xml" );
	page_setup_path = main_directory + Glib::ustring ( "/printer.page_setup" );
	printer_keyfile = new Glib::KeyFile ();
	// main window
	bldr->get_widget("main_window", main_window);
	bldr->get_widget ("main_notebook", main_notebook);
	main_notebook_page = 0;
	bldr->get_widget ("main_statusbar", main_statusbar);
	stbrItemSelId = main_statusbar->get_context_id ( Glib::ustring ( "ITEM_SELECT" ) );
	stbrItemDiskId = main_statusbar->get_context_id ( Glib::ustring ( "ITEM_DISK" ) );
	// main toolbar
	bldr->get_widget("main_toolbar", main_toolbar);
	bldr->get_widget("nuova_ricevuta_button", nuova_ricevuta_button);
	bldr->get_widget("nuova_prestazione_button", nuova_prestazione_button);
	bldr->get_widget("nuovo_cliente_button", nuovo_cliente_button);
	bldr->get_widget("modifica_selezione_toolbutton", modifica_selezione_toolbutton);
	bldr->get_widget("elimina_selezione_toolbutton", elimina_selezione_toolbutton);
	bldr->get_widget("chiusura_cassa_toolbutton", stampa_chiusura_toolbutton);
	// main menu
	bldr->get_widget ("main_menubar", main_menubar);
	bldr->get_widget ("nuova_ricevuta_imagemenuitem", nuova_ricevuta_menuitem);
	bldr->get_widget ("nuova_prestazione_imagemenuitem", nuova_prestazione_menuitem);
	bldr->get_widget ("nuovo_cliente_imagemenuitem", nuovo_cliente_menuitem);
	bldr->get_widget ("save_imagemenuitem", salva_menuitem);
	bldr->get_widget ("imposta_pagina_imagemenuitem", imposta_pagina_menuitem);
	bldr->get_widget ("print_ricevuta_imagemenuitem", stampa_ricevuta_menuitem);
	bldr->get_widget ("print_etichette_imagemenuitem", stampa_etichette_menuitem);
	bldr->get_widget ("print_chiusura_imagemenuitem", stampa_chiusura_menuitem);
	bldr->get_widget ("quit_imagemenuitem", quit_menuitem);
	bldr->get_widget ("modifica_selezione_imagemenuitem", modifica_selezione_menuitem);
	bldr->get_widget ("elimina_selezione_imagemenuitem", elimina_selezione_menuitem);
	bldr->get_widget ("preferenze_imagemenuitem", preferenze_menuitem);
	bldr->get_widget ("calendario_imagemenuitem", settimana_menuitem);
	bldr->get_widget ("ricevute_imagemenuitem", ricevute_menuitem);
	bldr->get_widget ("prestazioni_imagemenuitem", prestazioni_menuitem);
	bldr->get_widget ("clienti_imagemenuitem", clienti_menuitem);
	bldr->get_widget ("resoconto_imagemenuitem", resoconto_menuitem);
	bldr->get_widget ("about_imagemenuitem", about_menuitem);
	
	/**
	 * main notebook
	 * */
	
	// page calendario	
	ricevute_giorno_listmodel = new RicevuteGiornoListModel ();
	bldr->get_widget("calendario_lunedi_label", calendario_lunedi_label);
	ricevute_lunedi_liststore = Gtk::ListStore::create(*ricevute_giorno_listmodel);
	bldr->get_widget ("lunedi_treeview", ricevute_lunedi_treeview);
	ricevute_lunedi_treeview->set_model(ricevute_lunedi_liststore);
	numero_ricevuta_lunedi_treeviewcolumn = ricevute_lunedi_treeview->get_column(0);
	ricevute_lunedi_treeselection = ricevute_lunedi_treeview->get_selection ();
	ricevute_lunedi_treeselection->set_mode (Gtk::SELECTION_SINGLE);
	bldr->get_widget("totale_lunedi_label", totale_lunedi_label);
	bldr->get_widget("calendario_martedi_label", calendario_martedi_label);
	ricevute_martedi_liststore = Gtk::ListStore::create(*ricevute_giorno_listmodel);
	bldr->get_widget ("martedi_treeview", ricevute_martedi_treeview);
	ricevute_martedi_treeview->set_model(ricevute_martedi_liststore);
	numero_ricevuta_martedi_treeviewcolumn = ricevute_martedi_treeview->get_column(0);
	ricevute_martedi_treeselection = ricevute_martedi_treeview->get_selection ();
	ricevute_martedi_treeselection->set_mode (Gtk::SELECTION_SINGLE);
	bldr->get_widget("totale_martedi_label", totale_martedi_label);
	bldr->get_widget("calendario_mercoledi_label", calendario_mercoledi_label);
	ricevute_mercoledi_liststore = Gtk::ListStore::create(*ricevute_giorno_listmodel);
	bldr->get_widget ("mercoledi_treeview", ricevute_mercoledi_treeview);
	ricevute_mercoledi_treeview->set_model(ricevute_mercoledi_liststore);
	numero_ricevuta_mercoledi_treeviewcolumn = ricevute_mercoledi_treeview->get_column(0);
	ricevute_mercoledi_treeselection = ricevute_mercoledi_treeview->get_selection ();
	ricevute_mercoledi_treeselection->set_mode (Gtk::SELECTION_SINGLE);
	bldr->get_widget("totale_mercoledi_label", totale_mercoledi_label);
	bldr->get_widget("calendario_giovedi_label", calendario_giovedi_label);
	ricevute_giovedi_liststore = Gtk::ListStore::create(*ricevute_giorno_listmodel);
	bldr->get_widget ("giovedi_treeview", ricevute_giovedi_treeview);
	ricevute_giovedi_treeview->set_model(ricevute_giovedi_liststore);
	numero_ricevuta_giovedi_treeviewcolumn = ricevute_giovedi_treeview->get_column(0);
	ricevute_giovedi_treeselection = ricevute_giovedi_treeview->get_selection ();
	ricevute_giovedi_treeselection->set_mode (Gtk::SELECTION_SINGLE);
	bldr->get_widget("totale_giovedi_label", totale_giovedi_label);
	bldr->get_widget("calendario_venerdi_label", calendario_venerdi_label);
	ricevute_venerdi_liststore = Gtk::ListStore::create(*ricevute_giorno_listmodel);
	bldr->get_widget ("venerdi_treeview", ricevute_venerdi_treeview);
	ricevute_venerdi_treeview->set_model(ricevute_venerdi_liststore);
	numero_ricevuta_venerdi_treeviewcolumn = ricevute_venerdi_treeview->get_column(0);
	ricevute_venerdi_treeselection = ricevute_venerdi_treeview->get_selection ();
	ricevute_venerdi_treeselection->set_mode (Gtk::SELECTION_SINGLE);
	bldr->get_widget("totale_venerdi_label", totale_venerdi_label);
	bldr->get_widget("calendario_sabato_label", calendario_sabato_label);
	ricevute_sabato_liststore = Gtk::ListStore::create(*ricevute_giorno_listmodel);
	bldr->get_widget("sabato_treeview", ricevute_sabato_treeview);
	ricevute_sabato_treeview->set_model(ricevute_sabato_liststore);
	numero_ricevuta_sabato_treeviewcolumn = ricevute_sabato_treeview->get_column(0);
	ricevute_sabato_treeselection = ricevute_sabato_treeview->get_selection ();
	ricevute_sabato_treeselection->set_mode (Gtk::SELECTION_SINGLE);
	bldr->get_widget("totale_sabato_label", totale_sabato_label);
	bldr->get_widget("calendario_dettaglio_numero_label2", calendario_dettaglio_numero_label);
	bldr->get_widget("calendario_dettaglio_cliente_label2", calendario_dettaglio_cliente_label);
	bldr->get_widget("calendario_dettaglio_data_accettazione_label2", calendario_dettaglio_accettazione_label);
	bldr->get_widget("calendario_dettaglio_data_ritiro_label2", calendario_dettaglio_ritiro_label);
	bldr->get_widget("calendario_dettaglio_acconto_label2", calendario_dettaglio_acconto_label);
	bldr->get_widget("calendario_dettaglio_totale_label2", calendario_dettaglio_totale_label);
	prestazioni_ricevuta_treemodel = new PrestazioniRicevutaTreeModel ();
	calendario_dettaglio_prestazioni_treestore = Gtk::TreeStore::create(*prestazioni_ricevuta_treemodel);
	bldr->get_widget ("calendario_dettaglio_lista_treeview", calendario_dettaglio_prestazioni_treeview);
	calendario_dettaglio_prestazioni_treeview->set_model(calendario_dettaglio_prestazioni_treestore);
	calendario_dettaglio_prestazioni_treeview->append_column_editable (Glib::ustring("Completata"), prestazioni_ricevuta_treemodel->completata);
	calendario_dettaglio_prestazioni_treeview->append_column (Glib::ustring(""), prestazioni_ricevuta_treemodel->empty);
	calendario_dettaglio_prestazioni_treeselection = calendario_dettaglio_prestazioni_treeview->get_selection ();
	calendario_dettaglio_prestazioni_treeselection->set_mode (Gtk::SELECTION_SINGLE);
	completoTreeviewcolumn = calendario_dettaglio_prestazioni_treeview->get_column(4);
	completoTreeviewcolumn->set_sizing (Gtk::TREE_VIEW_COLUMN_AUTOSIZE);
	completoCellrenderertoggle = (Gtk::CellRendererToggle*)completoTreeviewcolumn->get_first_cell ();
	calendario_riepilogo_prestazioni_treestore = Gtk::TreeStore::create(*prestazioni_ricevuta_treemodel);
	bldr->get_widget ("calendario_riepilogo_prestazioni_treeview", calendario_riepilogo_prestazioni_treeview);
	calendario_riepilogo_prestazioni_treeview->set_model(calendario_riepilogo_prestazioni_treestore);
	
	// page ricevute
	ricevute_listmodel = new RicevuteListModel ();
	ricevute_liststore = Gtk::ListStore::create(*ricevute_listmodel);
	bldr->get_widget ("ricevute_treeview", ricevute_treeview);
	ricevute_treeview->set_model(ricevute_liststore);
	numero_ricevuta_treeviewcolumn = ricevute_treeview->get_column(0);
	ricevute_treeview->append_column_editable (Glib::ustring("Urgente"), ricevute_listmodel->urgente);
	ricevute_treeview->append_column_editable (Glib::ustring("Consegnato"), ricevute_listmodel->consegnato);
	ricevute_treeview->append_column (Glib::ustring(""), ricevute_listmodel->empty);
	ricevute_treeselection = ricevute_treeview->get_selection ();
	ricevute_treeselection->set_mode (Gtk::SELECTION_SINGLE);
	urgente_treeviewcolumn = ricevute_treeview->get_column(6);
	urgente_treeviewcolumn->set_sizing (Gtk::TREE_VIEW_COLUMN_AUTOSIZE);
	urgente_cellrenderertoggle = (Gtk::CellRendererToggle*)urgente_treeviewcolumn->get_first_cell ();
	consegnato_treeviewcolumn = ricevute_treeview->get_column(7);
	consegnato_treeviewcolumn->set_sizing (Gtk::TREE_VIEW_COLUMN_AUTOSIZE);
	consegnato_cellrenderertoggle = (Gtk::CellRendererToggle*)consegnato_treeviewcolumn->get_first_cell ();

	// menu contestuale ricevute
	bldr->get_widget ( "ricevute_context_menu", ricevute_context_menu);
	bldr->get_widget ( "modifica_ricevuta_context_menuitem", modifica_ricevute_context_menuitem);
	bldr->get_widget ( "elimina_ricevuta_context_menuitem", elimina_ricevute_context_menuitem);
	bldr->get_widget ( "stampa_ricevuta_context_menuitem", stampa_ricevute_context_menuitem);
	bldr->get_widget ( "stampa_etichetta_context_menuitem", stampa_etichette_context_menuitem);

	// page prestazioni
	prestazioni_listmodel = new PrestazioniListModel ();
	prestazioni_liststore = Gtk::ListStore::create(*prestazioni_listmodel);
	bldr->get_widget ("prestazioni_treeview", prestazioni_treeview);
	prestazioni_treeview->set_model(prestazioni_liststore);
	prestazioni_treeselection = prestazioni_treeview->get_selection ();
	prestazioni_treeselection->set_mode (Gtk::SELECTION_SINGLE);

	// page clienti
	clienti_listmodel = new ClientiListModel ();
	clienti_liststore = Gtk::ListStore::create(*clienti_listmodel);
	bldr->get_widget ("clienti_treeview", clienti_treeview);
	clienti_treeview->set_model(clienti_liststore);
	clienti_treeselection = clienti_treeview->get_selection ();
	clienti_treeselection->set_mode (Gtk::SELECTION_SINGLE);

	// menu contestuale generico
	bldr->get_widget ( "generic_context_menu", generic_context_menu);
	bldr->get_widget ( "edit_generic_context_menuitem", edit_generic_context_menuitem);
	bldr->get_widget ( "remove_generic_context_menuitem", remove_generic_context_menuitem);

	// page resoconto
	selezione_periodo_liststore = Gtk::ListStore::create(*button_popup_listmodel);
	bldr->get_widget ("periodo_resoconto_combobox", selezione_periodo_combobox);
	selezione_periodo_combobox->set_model(selezione_periodo_liststore);
	Glib::ustring periodi[] = { "giornaliero", "settimanale", "mensile" };
	vector<Glib::ustring> *periodi_vec = new vector<Glib::ustring> ( periodi, periodi + 3 );
	load_popup_button ( periodi_vec->begin(), periodi_vec->end(), selezione_periodo_liststore );
	delete periodi_vec;
	selezione_periodo_combobox->set_active ( 0 );
	bldr->get_widget ("ricevute_emesse_label2", resoconto_ricevute_emesse_label);
	bldr->get_widget ("prestazioni_effettuate_label2", resoconto_prestazioni_effettuate_label);
	bldr->get_widget ("clienti_serviti_label2", resoconto_clienti_serviti_label);
	bldr->get_widget ("incasso_totale_label2", resoconto_incasso_totale_label);
	ricevute_resoconto_listmodel = new RicevuteResocontoListModel ();
	ricevute_resoconto_liststore = Gtk::ListStore::create(*ricevute_resoconto_listmodel);
	bldr->get_widget ("ricevute_resoconto_treeview", ricevute_resoconto_treeview);
	ricevute_resoconto_treeview->set_model(ricevute_resoconto_liststore);
	numero_ricevuta_resoconto_treeviewcolumn = ricevute_resoconto_treeview->get_column(0);
	prestazioni_resoconto_liststore = Gtk::ListStore::create(*prestazioni_ricevuta_treemodel);
	bldr->get_widget ("prestazioni_resoconto_treeview", prestazioni_resoconto_treeview);
	prestazioni_resoconto_treeview->set_model(prestazioni_resoconto_liststore);
	clienti_resoconto_liststore = Gtk::ListStore::create(*clienti_listmodel);
	bldr->get_widget ("clienti_resoconto_treeview", clienti_resoconto_treeview);
	clienti_resoconto_treeview->set_model(clienti_resoconto_liststore);

	// nuova ricevuta window
	bldr->get_widget("new_ricevuta_window", new_ricevuta_window);
	bldr->get_widget("cliente_ricevuta_entry", cliente_ricevuta_entry);
	nome_cliente_entrycompletion = cliente_ricevuta_entry->get_completion ();
	nome_cliente_liststore = Gtk::ListStore::create(*button_popup_listmodel);
	nome_cliente_entrycompletion->set_model (nome_cliente_liststore);
	bldr->get_widget("suggerimento_cliente_button", trova_clienti_button);
	bldr->get_widget("data_accettazione_ricevuta_entry", data_accettazione_ricevuta_entry);
	bldr->get_widget("cambia_data_ricevuta_button1", cambia_data_ricevuta_button1);
	prestazioni_ricevuta_treestore = Gtk::TreeStore::create(*prestazioni_ricevuta_treemodel);
	bldr->get_widget("capi_prestazioni_ricevuta_treeview", prestazioni_ricevuta_treeview);
	prestazioni_ricevuta_treeview->set_model(prestazioni_ricevuta_treestore);
	prestazioni_ricevuta_treeview->append_column_editable (Glib::ustring("Prezzo"), prestazioni_ricevuta_treemodel->prezzo);
	prestazioni_ricevuta_treeselection = prestazioni_ricevuta_treeview->get_selection ();
	prestazioni_ricevuta_treeselection->set_mode (Gtk::SELECTION_SINGLE);
	prezzo_prestazione_treeviewcolumn = prestazioni_ricevuta_treeview->get_column(3);
	prezzo_prestazione_treeviewcolumn->set_sizing (Gtk::TREE_VIEW_COLUMN_AUTOSIZE);
	prezzo_prestazione_cellrenderertext = (Gtk::CellRendererText*)prezzo_prestazione_treeviewcolumn->get_first_cell ();
	bldr->get_widget("selezione_capo_combobox", selezione_capo_combobox);
	selezione_capo_liststore = Gtk::ListStore::create(*button_popup_listmodel);
	selezione_capo_combobox->set_model (selezione_capo_liststore);
	bldr->get_widget("selezione_prestazione_combobox", selezione_prestazione_combobox);
	selezione_prestazione_liststore = Gtk::ListStore::create(*button_popup_listmodel);
	selezione_prestazione_combobox->set_model (selezione_prestazione_liststore);
	bldr->get_widget("add_prestazione_ricevuta_button", add_prestazione_ricevuta_button);
	bldr->get_widget("rem_prestazione_ricevuta_button", rem_prestazione_ricevuta_button);
	bldr->get_widget("data_ritiro_ricevuta_entry", data_ritiro_ricevuta_entry);
	bldr->get_widget("cambia_data_ricevuta_button2", cambia_data_ricevuta_button2);
	bldr->get_widget("totale_ricevuta_label2", totale_ricevuta_label);
	bldr->get_widget("new_ricevuta_nonpagato_radiobutton", nonpagato_radiobutton);
	bldr->get_widget("new_ricevuta_pagato_radiobutton", pagato_radiobutton);
	bldr->get_widget("acconto_ricevuta_entry", acconto_ricevuta_entry);
	bldr->get_widget("stampa_ricevuta_checkbutton", stampa_ricevuta_checkbutton);
	bldr->get_widget("urgente_ricevuta_checkbutton", urgente_ricevuta_checkbutton);
	bldr->get_widget("annulla_ricevuta_button", new_ricevuta_cancel_button);
	bldr->get_widget("conferma_ricevuta_button", new_ricevuta_confirm_button);

	// nuova prestazione window
	bldr->get_widget("new_prestazione_window", new_prestazione_window);
	bldr->get_widget("capo_prestazione_entry", capo_prestazione_entry);
	capo_entrycompletion = capo_prestazione_entry->get_completion ();
	capo_liststore = Gtk::ListStore::create(*button_popup_listmodel);
	capo_entrycompletion->set_model (capo_liststore);
	bldr->get_widget("descrizione_prestazione_entry", descrizione_prestazione_entry);
	bldr->get_widget("prezzo_prestazione_entry", prezzo_prestazione_entry);
	bldr->get_widget("new_prestazione_confirm_button", new_prestazione_confirm_button);
	bldr->get_widget("new_prestazione_cancel_button", new_prestazione_cancel_button);

	// nuovo cliente window
	bldr->get_widget("new_cliente_window", new_cliente_window);
	bldr->get_widget("nome_cliente_entry", nome_cliente_entry);
	bldr->get_widget("telefono_cliente_entry", telefono_cliente_entry);
	bldr->get_widget("new_cliente_confirm_button", new_cliente_confirm_button);
	bldr->get_widget("new_cliente_cancel_button", new_cliente_cancel_button);

	// calendario window
	bldr->get_widget("calendario_window", calendario_window);
	bldr->get_widget("calendario", main_calendar);

	// preferenze window
	bldr->get_widget("preferenze_window", preferenze_window);
	bldr->get_widget("intestazione_preferenze_textview", intestazione_textview);
	intestazione_textbuffer = intestazione_textview->get_buffer ();
	bldr->get_widget("saluto_preferenze_textview", saluto_textview);
	saluto_textbuffer = saluto_textview->get_buffer ();
	bldr->get_widget("preferenze_salva_button", preferenze_salva_button);
	bldr->get_widget("preferenze_annulla_button", preferenze_annulla_button);
	bldr->get_widget("eliminazione_preferenze_combobox", eliminazione_ricevute_combobox);
	eliminazione_ricevute_liststore = Gtk::ListStore::create(*button_popup_listmodel);
	eliminazione_ricevute_combobox->set_model (eliminazione_ricevute_liststore);
	Glib::ustring frequenza[] = { "mai", "giornaliero", "settimanale", "mensile", "annuale" };
	vector<Glib::ustring> *frequenza_vec = new vector<Glib::ustring> ( frequenza, frequenza + 5 );
	load_popup_button ( frequenza_vec->begin(), frequenza_vec->end(), eliminazione_ricevute_liststore );
	eliminazione_ricevute_combobox->set_active (0);
	bldr->get_widget("azzeramento_preferenze_combobox", azzeramento_numero_combobox);
	azzeramento_numero_liststore = Gtk::ListStore::create(*button_popup_listmodel);
	azzeramento_numero_combobox->set_model (azzeramento_numero_liststore);
	load_popup_button ( frequenza_vec->begin() + 1, frequenza_vec->end(), azzeramento_numero_liststore );
	delete frequenza_vec;
	azzeramento_numero_combobox->set_active (0);
	bldr->get_widget("salvataggio_uscita_preferenze_combobox", salvataggio_uscita_combobox);
	salvataggio_uscita_liststore = Gtk::ListStore::create(*button_popup_listmodel);
	salvataggio_uscita_combobox->set_model (salvataggio_uscita_liststore);
	Glib::ustring scelta[] = { "automatico", "chiedi prima di salvare" };
	vector<Glib::ustring> *scelta_vec = new vector<Glib::ustring> ( scelta, scelta + 2 );
	load_popup_button ( scelta_vec->begin(), scelta_vec->end(), salvataggio_uscita_liststore );
	delete scelta_vec;
	salvataggio_uscita_combobox->set_active (0);
	bldr->get_widget("stampa_numero_ricevuta_preferenze_checkbutton", stampa_numero_ricevuta_checkbutton);
	bldr->get_widget("visualizza_numero_ricevuta_preferenze_checkbutton", visualizza_numero_ricevuta_checkbutton);

	// suggerimento clienti window
	bldr->get_widget("suggerimento_clienti_window", suggerimento_clienti_window);
	clienti_suggerimento_liststore = Gtk::ListStore::create(*clienti_listmodel);
	bldr->get_widget ("suggerimento_clienti_treeview", clienti_suggerimento_treeview);
	clienti_suggerimento_treeview->set_model(clienti_suggerimento_liststore);
	clienti_suggerimento_treeselection = clienti_suggerimento_treeview->get_selection ();

	// printing
	m_refPageSetup = Gtk::PageSetup::create();
	m_refSettings = Gtk::PrintSettings::create();

	connect_signals();
}

inline time_t Controller::
calcola_data_ritiro ( time_t tempo )
{
	struct tm *data_ora;
	tempo += TRE_GIORNI;
	data_ora = localtime (&tempo);
	while (DOMENICA || PRIMO_GENNAIO || EPIFANIA || LIBERAZIONE || PRIMO_MAGGIO || FESTA_REPUBBLICA || ASSUNZIONE || TUTTI_SANTI || IMMACOLATA || NATALE || SANTO_STEFANO || msu::is_lunedi_pasquetta(data_ora))
	{
		tempo += UN_GIORNO;
		data_ora = localtime(&tempo);
	}
	if (SABATO)
	{
		data_ora->tm_hour = 12;
		data_ora->tm_min = 0;
		data_ora->tm_sec = 0;
	}
	else
	{
		data_ora->tm_hour = 17;
		data_ora->tm_min = 30;
		data_ora->tm_sec = 0;
	}
	tempo = mktime(data_ora);
	return tempo;
}

inline time_t Controller::
parse_data_string ( const Glib::ustring &str )
{
	time_t tempo = time(NULL);
	struct tm *data_ora = localtime(&tempo);
	data_ora->tm_mday = atoi ( str.substr ( 4, 2 ).c_str() );
	data_ora->tm_mon = atoi ( str.substr ( 7, 2 ).c_str() ) - 1;
	data_ora->tm_year = atoi ( str.substr ( 10, 4 ).c_str() ) - 1900;
	data_ora->tm_hour = atoi ( str.substr ( 20, 2 ).c_str() );
	data_ora->tm_min = atoi ( str.substr ( 23, 2 ).c_str() );
	tempo = mktime(data_ora);
	return tempo;
}

inline void Controller::
calcola_periodo_tempo ( time_t &inizio, time_t &fine, char periodo )
{
	struct tm *data_ora;
	time_t tempo = time(NULL);
	data_ora = localtime ( &tempo );
	int oggi = data_ora->tm_wday;
	int oggi_m = data_ora->tm_mday;
	int oggi_y = data_ora->tm_yday;
	data_ora->tm_hour = 8;
	data_ora->tm_min = 0;
	data_ora->tm_sec = 0;
	tempo = mktime(data_ora);
	switch ( periodo )
	{
		case 0: // giornaliero
			inizio = tempo;
			data_ora->tm_hour = 23;
			data_ora->tm_min = 0;
			data_ora->tm_sec = 0;
			tempo = mktime(data_ora);
			fine = tempo;
			break;
		case 1: // settimanale
			inizio = tempo + ( (1 - oggi) * UN_GIORNO );
			data_ora->tm_hour = 20;
			data_ora->tm_min = 0;
			data_ora->tm_sec = 0;
			tempo = mktime(data_ora);
			fine = tempo + ( (6 - oggi) * UN_GIORNO );
			break;
		case 2: // mensile
			inizio = tempo + ( (1 - oggi_m) * UN_GIORNO );
			data_ora->tm_hour = 20;
			data_ora->tm_min = 0;
			data_ora->tm_sec = 0;
			tempo = mktime(data_ora);
			fine = tempo + ( (31 - oggi_m) * UN_GIORNO );
			break;
		case 3: // annuale
			inizio = tempo + ( (0 - oggi_y) * UN_GIORNO );
			data_ora->tm_hour = 20;
			data_ora->tm_min = 0;
			data_ora->tm_sec = 0;
			tempo = mktime(data_ora);
			fine = tempo + ( (365 - oggi_y) * UN_GIORNO );
			break;
	}
}

inline Controller::
~Controller()
{
	delete printer_keyfile;
	delete clienti;
	delete prestazioni;
	delete ricevute;
	delete button_popup_listmodel;
	delete clienti_listmodel;
	delete prestazioni_listmodel;
	delete prestazioni_ricevuta_treemodel;
	delete ricevute_listmodel;
	delete ricevute_giorno_listmodel;
	delete ricevute_resoconto_listmodel;
	delete mappa_capi;
}

#endif // _CONTROLLER_H_

